package com.rayo.accesscontrollercopy.module.setting;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import com.rayo.accesscontrollercopy.R;
import com.rayo.accesscontrollercopy.config.Constants;
import com.rayo.accesscontrollercopy.config.GlobalVariables;
import com.rayo.accesscontrollercopy.model.db.bean.KeyData;
import com.rayo.accesscontrollercopy.model.db.bean.SystemData;
import com.rayo.accesscontrollercopy.model.db.dao.KeyDataDao;
import com.rayo.accesscontrollercopy.model.db.dao.KeyDataImp;
import com.rayo.accesscontrollercopy.module.setting.view.VerticalStepView;
import com.rayo.accesscontrollercopy.utils.ToastUtils;
import com.rayo.keyholder.data.KeyHolderData;
import com.rayo.keyholder.serialport.KeyHolderService;
import com.rayo.wallreader.data.KeyBasicInfo;
import com.rayo.wallreader.serialport.OnPortListener;
import com.rayo.wallreader.serialport.PortClass;
import com.rayo.wallreader.serialport.ReaderPortThread;
import com.rayo.wallreader.utils.HexUtil;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

import static com.rayo.accesscontrollercopy.config.Constants.KEYTYPE;

public class BindKeyActivity extends AppCompatActivity {

    @BindView(R.id.stepview)
    VerticalStepView stepView;
    @BindView(R.id.tv_txt)
    TextView mTvTxt;
    private ReaderPortThread mReaderPortThread;
    private Thread mThread;
    public static KeyHolderService mKeyHolderService;
    private int step;
    private int Action;
    private boolean keyPlug = false;
    private String sendData;
    List<String> list = new ArrayList<>();
    private KeyData mKeyData;
    private AlertDialog alertDialog;
    private StringBuffer sb = new StringBuffer();
    private KeyDataDao dao = new KeyDataImp();
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case Constants.BACKLOCK:
                    Action = Constants.BACKLOCK;
                    mHandler.removeMessages(0);
                    byte[] keyBack = {0, 0, 0, 0};
                    mKeyHolderService.sendData(new KeyHolderData((byte) mKeyData.getType(), (byte) mKeyData.getAddress(), (byte) 0x02, keyBack));
                    break;
                case 0:
                    byte[] key = {};
                    mKeyHolderService.sendData(new KeyHolderData((byte) mKeyData.getType(), (byte) mKeyData.getAddress(), (byte) 0x01, key));
                    mHandler.sendEmptyMessageDelayed(0, 100);
                    break;
                case 2:
                   showDialog();
                    break;

//
            }

        }
    };



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bind_key);
        ButterKnife.bind(this);
        initView();
        initData();
    }

    private void initData() {
        Intent service = new Intent(this, KeyHolderService.class);
        bindService(service, mKeyHolderConnection, Context.BIND_AUTO_CREATE);
        registerReceiver(mKeyHolderReceiver, makeUpdateIntentFilter());
        mKeyData = (KeyData) getIntent().getSerializableExtra("data");
        mHandler.sendEmptyMessageDelayed(2,500);
    }

    private void initView() {
        list.add(getString(R.string.bind_get_keyplug));
        list.add(getString(R.string.bind_dialog_read_elce_key));
        list.add(getString(R.string.bind_dialog_bind_elcekey));
        list.add(getString(R.string.bind_dialog_insertkey));
        list.add(getString(R.string.bind_dialog_finish));

        setStepView(0);
    }


    private BroadcastReceiver mKeyHolderReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            StringBuilder stringBuilder = new StringBuilder(64);
            final String action = intent.getAction();
            if (intent.getSerializableExtra(KeyHolderService.EXTRA_DATA) instanceof Integer) {
                return;
            }
            final KeyHolderData keyHolderData = (KeyHolderData) intent.getSerializableExtra(KeyHolderService.EXTRA_DATA);

            switch (action) {

                case KeyHolderService.ACTION_DATA_WRITE:
                    stringBuilder.append("MainSend:");
                    stringBuilder.append(HexUtil.encodeHexStr(keyHolderData.getData()));
                    sendData = HexUtil.encodeHexStr(keyHolderData.getData());
                    Log.e("write", stringBuilder.toString());
                    break;
                case KeyHolderService.ACTION_DATA_READ:
                    Log.e("cmd", keyHolderData.getCmd() + "");
                    stringBuilder.append("MainRead:");
                    stringBuilder.append(String.format("%02X", keyHolderData.getCmd()) + "-");
                    stringBuilder.append(String.format("%02X", keyHolderData.getDeviceType()) + "-");
                    stringBuilder.append(String.format("%02X", keyHolderData.getAddress()) + "-");
                    stringBuilder.append(HexUtil.encodeHexStr(keyHolderData.getData()));

                    Log.e("read", stringBuilder.toString());

                    if (keyHolderData.getCmd() == 2) {
                        if (HexUtil.encodeHexStr(keyHolderData.getData()).equals("01")) {

                            switch (Action) {
                                case Constants.OPENDOOR://开门
                                    Action = Constants.GETKEYPLUG;
                                    byte[] key = {1, 1, 0, 0};
                                    mKeyHolderService.sendData(new KeyHolderData((byte) mKeyData.getType(), (byte) mKeyData.getAddress(), (byte) 0x02, key));
                                    break;
                                case Constants.GETKEYPLUG://开控制器
                                    Action = Constants.CHECKGETKEY;
                                    mHandler.sendEmptyMessage(0);
                                    mHandler.sendEmptyMessageDelayed(Constants.BACKLOCK, 30000);
                                    break;
                                case Constants.CLOSECONTROLLER://关控制器
                                    setStepView(1);
                                    doListen();
                                    break;
                                case Constants.OPENDOOR_REYURN:
                                    Action = Constants.OPENCONTROLLER_RETURN;
                                    byte[] keyOpen = {1, 1, 0, 0};
                                    mKeyHolderService.sendData(new KeyHolderData((byte) mKeyData.getType(), (byte) mKeyData.getAddress(), (byte) 0x02, keyOpen));
                                    break;
                                case Constants.OPENCONTROLLER_RETURN:
                                    Action = Constants.CHECKRETURNKEY;
                                    mHandler.sendEmptyMessage(0);
                                    mHandler.sendEmptyMessageDelayed(Constants.BACKLOCK, 30000);
                                    break;
                                case Constants.CLOSECONTROLLER_RETURN://关控制器
                                   setStepView(5);

                                    mKeyData.setState(1);
                                    dao.updateKeyData(mKeyData);
                                    ToastUtils.showShortToast(BindKeyActivity.this,getString(R.string.bind_success));
                                    BindKeyActivity.this.setResult(RESULT_OK);
                                    finish();
                                    break;
                                case Constants.BACKLOCK:
                                    ToastUtils.showShortToast(BindKeyActivity.this,getString(R.string.time_out));
                                    finish();
                                    break;
                            }
                        }
                    } else if (keyHolderData.getCmd() == 1) {

                        if ((HexUtil.encodeHexStr(keyHolderData.getData()).startsWith("01", 0))) {

                            switch (Action) {
                                case Constants.CHECKPLUG://检查钥匙栓是否在箱中
                                    if (!HexUtil.encodeHexStr(keyHolderData.getData()).substring(14, 22).equals("00000000")) {
                                        Action = Constants.CHECKDOOR;
                                        byte[] key = {};
                                        mKeyHolderService.sendData(new KeyHolderData((byte) 1, (byte) mKeyData.getKeybox(), (byte) 0x01, key));

                                    } else {
                                        setStepView(1);
                                        doListen();
                                    }
                                    break;
                                case Constants.CHECKDOOR://检查门状态
                                    if (HexUtil.encodeHexStr(keyHolderData.getData()).substring(22, 24).equals("01")) {//01开
                                        Action = Constants.GETKEYPLUG;
                                        byte[] key = {1, 1, 0, 0};
                                        mKeyHolderService.sendData(new KeyHolderData((byte) mKeyData.getType(), (byte) mKeyData.getAddress(), (byte) 0x02, key));
                                    } else {
                                        Action = Constants.OPENDOOR;
                                        byte[] key = {1, 0, 0, 0};
                                        mKeyHolderService.sendData(new KeyHolderData((byte) 1, (byte) mKeyData.getKeybox(), (byte) 0x02, key));
                                    }
                                    break;
                                case Constants.CHECKDOOR_RETURN:
                                    if (HexUtil.encodeHexStr(keyHolderData.getData()).substring(22, 24).equals("01")) {//01开
                                        Action = Constants.OPENCONTROLLER_RETURN;
                                        byte[] keyOpen = {1, 1, 0, 0};
                                        mKeyHolderService.sendData(new KeyHolderData((byte) mKeyData.getType(), (byte) mKeyData.getAddress(), (byte) 0x02, keyOpen));
                                    } else {
                                        Action = Constants.OPENDOOR_REYURN;
                                        byte[] key = {1, 0, 0, 0};
                                        mKeyHolderService.sendData(new KeyHolderData((byte) 1, (byte) mKeyData.getKeybox(), (byte) 0x02, key));
                                    }
                                    break;
                                case Constants.CHECKGETKEY://监测钥匙栓取出
                                    if (HexUtil.encodeHexStr(keyHolderData.getData()).substring(14, 22).equals("00000000")) {
                                        mHandler.removeMessages(Constants.BACKLOCK);
                                        mHandler.removeMessages(0);
                                        Action = Constants.CLOSECONTROLLER;
                                        byte[] key = {0, 0, 0, 0};
                                        mKeyHolderService.sendData(new KeyHolderData((byte) mKeyData.getType(), (byte) mKeyData.getAddress(), (byte) 0x02, key));
                                    }
                                    break;
                                case Constants.CHECKRETURNKEY://监测钥匙栓还入
                                    if (!HexUtil.encodeHexStr(keyHolderData.getData()).substring(14, 22).equals("00000000")
                                            && HexUtil.encodeHexStr(keyHolderData.getData()).substring(22, 24).equals("01")) {
                                        sb.append(getString(R.string.bind_key_tagid,":")+HexUtil.encodeHexStr(keyHolderData.getData()).substring(14, 22)+"\n\n");

                                        mTvTxt.setText(sb.toString());
                                        mKeyData.setTagid(HexUtil.encodeHexStr(keyHolderData.getData()).substring(14, 22));
                                        mHandler.removeMessages(Constants.BACKLOCK);
                                        mHandler.removeMessages(0);
                                        Action = Constants.CLOSECONTROLLER_RETURN;
                                        byte[] key = {0, 0, 0, 0};
                                        mKeyHolderService.sendData(new KeyHolderData((byte) mKeyData.getType(), (byte) mKeyData.getAddress(), (byte) 0x02, key));
                                    }
                                    break;
                            }

                        }

                    }

                    break;
                case KeyHolderService.ACTION_CLOSE:
                    break;
                default:
                    break;
            }
        }
    };
    private ServiceConnection mKeyHolderConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mKeyHolderService = ((KeyHolderService.LocalBinder) service).getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mKeyHolderService = null;

        }
    };

    private IntentFilter makeUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(KeyHolderService.ACTION_DATA_READ);
        intentFilter.addAction(KeyHolderService.ACTION_DATA_WRITE);
        intentFilter.addAction(KeyHolderService.ACTION_CLOSE);
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        return intentFilter;
    }

    public void setStepView(int i) {

        stepView.setStepsViewIndicatorComplectingPosition(i)//设置完成的步数
                .reverseDraw(false)//default is true
                .setStepViewTexts(list)//总步骤
                .setLinePaddingProportion(1.5f)//设置indicator线与线间距的比例系数
                .setStepsViewIndicatorCompletedLineColor(ContextCompat.getColor(this, R.color.Black))//设置StepsViewIndicator完成线的颜色
                .setStepsViewIndicatorUnCompletedLineColor(ContextCompat.getColor(this, R.color.Gery))//设置StepsViewIndicator未完成线的颜色
                .setStepViewComplectedTextColor(ContextCompat.getColor(this, android.R.color.black))//设置StepsView text完成线的颜色
                .setStepViewUnComplectedTextColor(ContextCompat.getColor(this, R.color.Gery))//设置StepsView text未完成线的颜色
                .setStepsViewIndicatorCompleteIcon(ContextCompat.getDrawable(this, R.drawable.icon_finish))//设置StepsViewIndicator CompleteIcon
                .setStepsViewIndicatorDefaultIcon(ContextCompat.getDrawable(this, R.drawable.unfinish))//设置StepsViewIndicator DefaultIcon
                .setStepsViewIndicatorAttentionIcon(ContextCompat.getDrawable(this, R.drawable.attention));//设置StepsViewIndicator AttentionIcon
    }

    public void doListen() {
        List<PortClass> port = new ArrayList<>();
        PortClass portClass = new PortClass();
        portClass.setPort(PortClass.DETIVER_2);
        portClass.setCard(true);
        port.add(portClass);

        final KeyBasicInfo mKeyBasicInfo = new KeyBasicInfo();
        mReaderPortThread = new ReaderPortThread(port) {
            @Override
            protected void onSendNfcKeyReader(String s, int i) {
                mKeyBasicInfo.setKeyType(KeyBasicInfo.NFC_KEY);
                mReaderPortThread.getmPortReadBiz().findKey(mKeyBasicInfo, new OnPortListener.OnFindListener() {
                    @Override
                    public void findSuccess() {

                    }

                    @Override
                    public void findFailed() {
                    }
                });
            }

            @Override
            protected void onSendBleKeyReader(String s, int i) {
                mKeyBasicInfo.setKeyType(KeyBasicInfo.BLE_KEY);
//                mKeyBasicInfo.setSysCode(HexUtil.decodeHex(GlobalVariables.getInstance().getmSiteData().getSyscode().toCharArray()));
//                mKeyBasicInfo.setRegCode(HexUtil.decodeHex(GlobalVariables.getInstance().getmSiteData().getRegcode().toCharArray()));
                mReaderPortThread.getmPortReadBiz().findKey(mKeyBasicInfo, new OnPortListener.OnFindListener() {
                    @Override
                    public void findSuccess() {
                        String txt = "Find key successfully \n";
                        txt += "Key Id: " + mKeyBasicInfo.getKeyId() + "\n";
                        txt += "Key Type: "
                                + String.format("%2X", mKeyBasicInfo.getType())
                                + "\n";
                        txt += "Key Group Id: " + mKeyBasicInfo.getGroupId()
                                + "\n";
                        txt += "Key Version: " + mKeyBasicInfo.getVersion()
                                + "\n";
                        txt += "Key Serial Number: "
                                + com.litesuits.common.utils.HexUtil.encodeHexStr(mKeyBasicInfo
                                .getSerial()) + "\n";
                        mKeyData.setSerialnumber(com.litesuits.common.utils.HexUtil.encodeHexStr(mKeyBasicInfo
                                .getSerial()));
                        mKeyData.setVersion(mKeyBasicInfo.getVersion());
                        mKeyData.setState(1);

                        if (checkSerial(HexUtil.encodeHexStr(mKeyBasicInfo.getSerial()))) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    sb.append(getString(R.string.bind_key_serial, ":") + HexUtil.encodeHexStr(mKeyBasicInfo.getSerial())+"\n\n");
                                    sb.append(getString(R.string.bind_key_version, ":") + mKeyBasicInfo.getVersion()+"\n\n");
                                  mTvTxt.setText(sb.toString());
                                  setStepView(2);
                                    showHintDialog();

                                }
                            });

//                            if (keyPlug){
//                                Action = Constants.CHECKDOOR;
//                                byte[] key = {};
//                                mKeyHolderService.sendData(new KeyHolderData((byte) 1, (byte) mKeyData.getBoxid(), (byte) 0x01, key));
//                            }else {
//                                runOnUiThread(new Runnable() {
//                                    @Override
//                                    public void run() {
//
//                                        getView().setStepView(2);
//                                        getView().showHintDialog();
//
//                                    }
//                                });
//                            }

                        } else {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                 showKeyWrongDialog();

                                }
                            });

                        }

                        mReaderPortThread.stop();
                    }

                    @Override
                    public void findFailed() {
                        mReaderPortThread.stop();
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                               showWrongDialog();

                            }
                        });
                    }
                });
            }

            @Override
            protected void onSendCardReader(String s, int i, byte[] bytes) {

            }

            @Override
            protected void onNoReader(String s, int i) {

            }

            @Override
            protected void onPlugInRelay(String s, int i) {

            }

            @Override
            protected void onStopReader() {

            }

        };
        mThread = new Thread(mReaderPortThread);
        mThread.start();
    }

    private void showWrongDialog() {
        alertDialog = new AlertDialog.Builder(this)
                .setTitle(getString(R.string.warn))
                .setMessage(getString(R.string.bind_dialog_connect_key_fail))
                .setPositiveButton(getString(R.string.okay), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        doListen();
                        dialog.dismiss();
                    }
                })
                .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        finish();
                    }
                }).create();
        alertDialog.show();
    }

    private void showKeyWrongDialog() {
        alertDialog = new AlertDialog.Builder(this)
                .setTitle(getString(R.string.warn))
                .setMessage(getString(R.string.bind_dialog_bindkey_fail))
                .setPositiveButton(getString(R.string.okay), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                       doListen();
                        dialog.dismiss();
                    }
                })
                .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        finish();
                    }
                }).create();
        alertDialog.show();
    }


    private void showDialog() {
        alertDialog = new AlertDialog.Builder(this)
                .setTitle(getString(R.string.warn))
                .setMessage(getString(R.string.bind_dialog_bind_key))
                .setPositiveButton(getString(R.string.okay), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        sb.append(getString(R.string.bind_dialog_control_address, ":") + mKeyData.getAddress()+"\n\n");
                        mTvTxt.setText(sb.toString());
                        Action = Constants.CHECKPLUG;
                        byte[] key = {};
                        sendData(new KeyHolderData((byte) mKeyData.getType(), (byte) mKeyData.getAddress(), (byte) 0x01, key), 0);
                        dialog.dismiss();
                    }
                })
                .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        finish();
                    }
                }).create();
        alertDialog.show();

    }
    private void showHintDialog() {
        alertDialog = new AlertDialog.Builder(this)
                .setTitle(getString(R.string.warn))
                .setMessage(getString(R.string.bind_dialog_bind_device_key))
                .setPositiveButton(getString(R.string.okay), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        setStepView(3);
                        byte[] key = {};
                        sendData(new KeyHolderData((byte) 1, (byte) mKeyData.getKeybox(), (byte) 0x01, key), 1);
                        dialog.dismiss();
                    }
                })
                .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                }).create();
        alertDialog.show();
    }

    private boolean checkSerial(String s) {
        KeyData keyData = dao.getKeyDataBySerialnumber(s);
        if (keyData!=null)
            return false;
        else
            return true;
    }

    public void sendData(KeyHolderData keyHolderData, int step) {
        if (step == 0) {
            Action = Constants.CHECKPLUG;
        } else if (step == 1) {
            keyPlug = false;
            Action = Constants.CHECKDOOR_RETURN;//1
        }
        mKeyHolderService.sendData(keyHolderData);
    }

    private void stop() {
        if (mReaderPortThread != null && !mReaderPortThread.isStop) {
            mReaderPortThread.stop();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stop();
        if (mKeyHolderService != null) {
            Action = 0;
            byte[] key = {0, 0, 0, 0};
            mKeyHolderService.sendData(new KeyHolderData((byte) mKeyData.getType(), (byte) mKeyData.getAddress(), (byte) 0x02, key));
        }
        mHandler.removeCallbacksAndMessages(null);
        unregisterReceiver(mKeyHolderReceiver);
        try {
            if (mKeyHolderConnection != null)
                unbindService(mKeyHolderConnection);
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("exx", e.toString());
        }
    }
}
